﻿@page "/security/index"
@attribute [Authorize]

@inject IUserService UserService
@inject IRoleService RoleService
@inject IPermissionService PermissionService
@inject DialogService DialogService
@inject NotificationService NotificationService

<RadzenCard Variant="Variant.Filled" Style="height : 100%;">
    <RadzenSplitter Orientation="Orientation.Vertical" style="height: 100%;">
        <RadzenSplitterPane Size="100px">
            <RadzenSplitter>
                <RadzenSplitterPane Size="20%" Min="20%" Max="30%">
                    <RadzenListBox TValue="RoleInfoResponseDto" Data=@RoleList TextProperty="RoleName" SelectedItem="_selectedValue"
                                   ValueProperty="Key" Change="@ListSelectedValueChanged"
                                   Style="width: 100%;  height: 100%" />
                </RadzenSplitterPane>
                <RadzenSplitterPane>
                    <RadzenTabs RenderMode="TabRenderMode.Client" SelectedIndex=@_selectedIndex SelectedIndexChanged="SelectedIndexChangedHandler" Style="height:100%;">
                        <Tabs>
                            <RadzenTabsItem Text="菜单授权">
                                <RadzenStack>
                                    <RadzenRow>
                                        <RadzenColumn>
                                            <RadzenButton Click="SaveMenuHandler" Text="保存菜单"></RadzenButton>
                                        </RadzenColumn>
                                    </RadzenRow>
                                    <SecurityMenu @ref="_securityMenu" TreeData="TreeData"></SecurityMenu>
                                </RadzenStack>
                            </RadzenTabsItem>
                            <RadzenTabsItem Text="用户授权">
                                <RadzenStack>
                                    <SearchFormPartial Model="_searchRequestDto" QueryHandler="QueryHandler"></SearchFormPartial>

                                    <SearchTablePartial @ref="_requestTable" T="UserInfoResponseDto" ServerData="ServerReload">
                                        <ToolbarContent>
                                            <RadzenRow>
                                                <RadzenColumn>
                                                    <RadzenButton ButtonStyle="ButtonStyle.Primary" Icon="edit" Size="ButtonSize.Medium"
                                                                  Shade="Shade.Lighter" Variant="Variant.Flat"
                                                                  Click=AddUserHandler @onclick:stopPropagation="true">
                                                        添加用户
                                                    </RadzenButton>
                                                </RadzenColumn>
                                            </RadzenRow>
                                        </ToolbarContent>
                                        <TemplateColumnContent>
                                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Medium"
                                                          Shade="Shade.Lighter" Variant="Variant.Flat"
                                                          Click=@(args => GridUnSelectButtonClick(args, context)) @onclick:stopPropagation="true" />
                                        </TemplateColumnContent>
                                    </SearchTablePartial>
                                </RadzenStack>
                            </RadzenTabsItem>
                        </Tabs>
                    </RadzenTabs>
                </RadzenSplitterPane>
            </RadzenSplitter>
        </RadzenSplitterPane>
    </RadzenSplitter>
</RadzenCard>
@code {
    private int _selectedIndex = 0;

    private object _selectedValue;
    protected IList<RoleInfoResponseDto> RoleList = new List<RoleInfoResponseDto>();

    private SecurityMenu _securityMenu;
    protected IList<PermissionTreeResponseDto> TreeData = new List<PermissionTreeResponseDto>();

    private readonly UserSearchRequestDto _searchRequestDto = new();
    protected IEnumerable<UserInfoResponseDto> PagedData = new List<UserInfoResponseDto>();
    private SearchTablePartial<UserInfoResponseDto> _requestTable = new();
    protected int TotalItems;

    protected override async Task OnInitializedAsync()
    {
        // 获取所有角色信息
        var roleResult = await RoleService.QueryRoles(new RoleSearchRequestDto());
        if (roleResult != null && roleResult.Succeeded)
        {
            RoleList = roleResult.Data;
        }

        // 获取所有权限信息
        var result = await PermissionService.QueryPermissionsByTree(0);
        if (result != null && result.Succeeded)
        {
            TreeData = result.Data;
        }
    }

    async Task ListSelectedValueChanged(object item)
    {
        if (item != null)
        {
            _selectedValue = item;

            if (_selectedIndex == 0)
            {
                await GetSelectedItems();
            }
            else if (_selectedIndex == 1)
            {
                await _requestTable.ReloadServerData();
            }

        }
    }

    async Task SelectedIndexChangedHandler(int item)
    {
        _selectedIndex = item;

        if (_selectedValue != null)
        {
            if (item == 0)
            {
                await GetSelectedItems();
            }
            else if (item == 1)
            {
                await _requestTable.ReloadServerData();
            }
        }
    }

    private async Task GetSelectedItems()
    {
        // 获取角色下的权限信息
        var result = await RoleService.QueryPermissionsByRole(Guid.Parse(_selectedValue.ToString() ?? string.Empty));
        if (result.Succeeded)
        {
            var list = result.Data.Select(i => i.Value).ToList();

            IList<PermissionTreeResponseDto> defaultSelectedTree = new List<PermissionTreeResponseDto>();

            GetChildSelectedItems(list, TreeData, defaultSelectedTree);

            _securityMenu.SetDefaultSelected(defaultSelectedTree.Cast<object>());
        }

    }

    private void GetChildSelectedItems(List<string> resultData,
        IList<PermissionTreeResponseDto> treeResponseDtos,
        IList<PermissionTreeResponseDto> permissionTreeResponseDtos)
    {
        foreach (var childItem in treeResponseDtos)
        {
            if (childItem.Children != null)
            {
                GetChildSelectedItems(resultData, childItem.Children, permissionTreeResponseDtos);
            }

            var item = childItem;
            if (resultData.Any(i => i.Equals(item.Code)))
            {
                permissionTreeResponseDtos.Add(childItem);
            }
        }
    }

    async Task QueryHandler(MouseEventArgs args)
    {
        await _requestTable.ReloadServerData();
    }

    private async Task<ODataServiceResult<UserInfoResponseDto>> ServerReload(LoadDataArgs state)
    {
        if (state.Skip != null) _searchRequestDto.Page = (int)(state.Skip + 1);
        if (state.Top != null) _searchRequestDto.Limit = (int)state.Top;

        if (_selectedValue != null)
        {

            var data = await RoleService.QueryUsersByRole(Guid.Parse(_selectedValue.ToString() ?? string.Empty), _searchRequestDto);

            if (data != null)
            {
                PagedData = data.Data;
                TotalItems = data.TotalCount;
            }
        }

        return new ODataServiceResult<UserInfoResponseDto>() { Count = TotalItems, Value = PagedData };
    }

    async Task GridUnSelectButtonClick(MouseEventArgs args, UserInfoResponseDto item)
    {
        var confirmFlag = await DialogService.Confirm("Are you sure?", "MyTitle", new ConfirmOptions()
            {
                OkButtonText = "Yes",
                CancelButtonText = "No"
            });

        if (confirmFlag == true)
        {
            var result = await RoleService.UpdateUsersByRole(Guid.Parse(_selectedValue.ToString() ?? string.Empty), new RoleOperateRequestDto()
                {
                    OperateType = "Delete",
                    UserNames = new List<string>() { item.UserName }
                });

            if (result.Succeeded)
            {
                NotificationService.Notify(new NotificationMessage
                    {
                        Severity = NotificationSeverity.Success,
                        Summary = "提示",
                        Detail = "保存成功",
                        Duration = 4000
                    });
                await _requestTable.ReloadServerData();
            }
        }

    }

    async Task AddUserHandler(MouseEventArgs args)
    {
        if (_selectedValue == null)
        {
            NotificationService.Notify(new NotificationMessage
                {
                    Severity = NotificationSeverity.Warning,
                    Summary = "提示",
                    Detail = "请选择角色",
                    Duration = 4000
                });

            return;
        }

        await DialogService.OpenAsync<SecurityUser>("Select User",
            new Dictionary<string, object> { { "RoleId", Guid.Parse(_selectedValue.ToString() ?? string.Empty) } });
        await _requestTable.ReloadServerData();
    }

    // 保存菜单
    async Task SaveMenuHandler(MouseEventArgs args)
    {
        var list = _securityMenu.GetSelected().Select(i => i.Code).ToList();

        if (_selectedValue == null || list.Count == 0)
        {
            NotificationService.Notify(new NotificationMessage
                {
                    Severity = NotificationSeverity.Warning,
                    Summary = "提示",
                    Detail = "请选择角色",
                    Duration = 4000
                });

            return;
        }

        var result = await RoleService.UpdatePermissionsByRole(Guid.Parse(_selectedValue.ToString() ?? string.Empty), list);
        if (result.Succeeded)
        {
            NotificationService.Notify(new NotificationMessage
                {
                    Severity = NotificationSeverity.Success,
                    Summary = "提示",
                    Detail = "保存成功",
                    Duration = 4000
                });
        }
    }

}